/**
 * 
 *  @project Air Traff Monitor
 * 
 *  @author M.Emre ATASEVER <m.emre.atas@gmail.com>
 *  @author M.Burak ALKAN <mburakalkan@gmail.com>
 *  @author H.Burak KARAMIK <bkaramik@gmail.com>
 *
 *	`Air Traffic Monitor' is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <protprops.h>
#include <QVariant>
#include <QDateTime>

static QStringList NetOptions,NetNames,CliOptions,CliNames,AleOptions,AleNames,InfOptions,InfNames,CrdNames,CrdOptions;
static QString NetName,AleName,CliName,InfName,CardName;



void QKismetOptions::setOptions(QStringList options)
{
	//selected = options;
	int j	= options.size();
	for(int i = 0;i < j;i++)
		setOption(options[i],true);
	//reIdx();
}

const QList<int>* QKismetOptions::getIdx()
{
	return &idx;
}
const QStringList* QKismetOptions::getCaps()
{
	return Caps;
}

const QStringList* QKismetOptions::getSelected()
{
	return &selected;
}

const QStringList* QKismetOptions::getNames()
{
	return Names;
}

void QKismetOptions::reIdx()
{
	int j = selected.size();
	idx.clear();
	for(int i = 0;i < j;i++)
	{
		idx.append(Caps->indexOf(selected[i]));
	}
}

bool QKismetOptions::setOption(QString option,bool enable)
{
	int i;
	int j = selected.size();
	if(enable)
	{
		i = Caps->indexOf(option);
		if(i == -1)
			return false;
		refc[i]++;
		int k = 0;
		for(;k < j;k++)
		{
			if(i < Caps->indexOf(selected[k]))
				break;
		}
		selected.insert(k,option);
	}
	else
	{
		i = selected.indexOf(option);
		if(i == -1)
			return false;
		int r	= Caps->indexOf(option);
		if(--(refc[r]) == 0)
			selected.removeAt(i);
	}
	reIdx();
	return true;
}

QByteArray QKismetOptions::optionsString(int idx)
{
	QByteArray com = "!";
	com += QByteArray::number(idx);
	com += " ENABLE ";
	com += *cName;
	com += " ";
	com += selected.join(",");
	com += "\r\n";	
	return com;
}
QKismetOptions::~QKismetOptions()
{
	delete [] refc;
}
NetworkOptions::NetworkOptions()
{
	if(NetOptions.size() == 0)
	{
	NetName	= "NETWORK";

	NetOptions <<	"bssid" << "type" << 
		"ssid" << "channel" << 
		"rangeip"<< "maxrate"<< 
		"wep" << "beaconinfo" << 
		"firsttime" << "lasttime" << 
		"atype" << "gpsfixed" << 
		"octets" << "cloaked" << 
		"beaconrate"  << "manufkey" << 
		"manufscore" << "datasize"  << 
		"carrierset" << "maxseenrate" << 
		"encodingset" << "decrypted" << 
		"bsstimestamp"

		<< "turbocellnid" << "turbocellmode" << "turbocellsat"

		<< "maxlat" << "maxlon" << 
		"maxalt" <<  "bestlat" << 
		"bestlon" << "bestalt" << 
		"agglat" << "agglon" << 
		"aggalt" << "aggpoints" << 
		"minlat" << "minlon" << 
		"minalt" << "minspd" <<  
		"maxspd" 

		<< "llcpackets" << "datapackets" << 
		"cryptpackets" << "weakpackets" << 
		"dupeivpackets"

		<< "quality" << "signal" << 
		"noise" << "bestquality" << 
		"bestsignal" << "bestnoise";

	NetNames << "BSSID" << "Network type" << 
		"SSID" << "Channel" << 
		"IP range" << "Max rate" << 
		"WEP" << "Beacon info" << 
		"First time seen" << 
		"Last time seen" << "Address type" << 
		"GPS fixed" << "Octets" << 
		"Cloaked" << "Beacon rate" << 
		"Manufacturer key" << "Manufacturer score" << 
		"Data size" << "Carrier" << 
		"Max seen rate" << "Encoding" << 
		"Decrypted" << "BSS timestamp";

	NetNames << "Network ID" << "Mode" << "Sattelite";
	
	NetNames << "Max latitude" << "Max longitude" << 
		"Max altitude"<< "Best latitude" << 
		"Best longitude" << "Best altitude"<< 
		"Aggregate latitude" << "Aggregate longitude" << 
		"Aggregate altitude"<< "Aggregate points" << 
		"Min latitude" << "Min longitude" << 
		"Min altitude" << "Min speed" << 
		"Max speed";
	
	NetNames << "Logical link control packets" << 
		"Data packets" << "Crypted packets" << 
		"Weak packets" << "Duplicate IV packets";

	NetNames << "Quality" << "Signal" <<
		"Noise" << "Best quality" <<
		"Best signal" << "Best noise";
	
	}
	Caps	= &NetOptions;
	Names	= &NetNames;
	cName	= &NetName;
	
	refc	= new int[Names->size()];
	memset(refc,0,sizeof(int)*Names->size());
}
QString NetworkOptions::print(QVariant *v, int i)
{
	switch(i)
	{
		//Network type
		case 1:
			switch(v->toInt())
			{
				case 0:	return "Access point";
					break;
				case 1:	return "Ad-Hoc";
					break;
				case 2:	return "Probe";
					break;
				case 3: return "Turbocell";
					break;
				case 4: return "Data";
					break;
				default:
					return "?";
			}
			break;
		//Max rate
		case 5:	return v->toString() + " Mb/s";
			break;
		//Encryption
		case 6:	{
				i = v->toInt();
				if(i == 0)
					return "None";
				QString ret;
				if(i & 0x00010000)
					ret	= "CCMP ";
				if(i & 0x00008000)
					ret	+= "PPTP ";
				if(i & 0x00004000)
					i	-= 8192;
				if(i & 0x00002000)
					ret	+= "PEAP ";
				if(i & 0x00001000)
					ret	+= "TLS ";
				if(i & 0x00000800)
					ret	+= "TTLS ";
				if(i & 0x00000400)
					ret	+= "LEAP ";
				if(i & 0x00000200)
					ret	+= "AES/CCM ";
				if(i & 0x00000100)
					ret	+= "AES/OCB ";
				if(i & 0x00000080)
					ret	+= "PSK ";
				if(i & 0x00000040)
					ret	+= "WPA ";
				if(i & 0x00000020)
					ret	+= "TKIP ";
				if(i & 0x00000010)
					ret	+= "WEP 104 ";
				if(i & 0x00000008)
					ret	+= "WEP40 ";
				if(i & 0x00000004)
					ret	+= "Layer 3 ";
				if(i & 0x00000002)
					ret	+= "WEP ";
				if(i & 0x00000001)
					ret	+= "Unknown";
				return ret;// += v->toString();;
			
			}
			break;
		//Various times
		case 8:
		case 9:	{
				QDateTime t;
				t.setTime_t(v->toInt());
				return  t.toString("hh:mm:ss");
			}
			break;
		//Address type
		case 10:
			switch(v->toInt())
			{
				case 1: return "Factory";
				case 2:	return "UDP";
				case 3: return "ARP";
				case 4: return "TCP";
				case 5: return "DHCP";
				case 6: return "Group";
				default: return "";
			}
			break;
		//Cloaked
		case 13:
		case 21:
			if(v->toInt())
				return "Yes";
			else
				return "No";
		//Data size
		case 17:
			i	= v->toInt();
			if(i < 1024)
				return QString::number(i) + " B";
			else if(i < 1024*1024)
				return QString::number(i/1024) + " KB";
			else if(i < 1024*1024*1024)
				return QString::number(i/(1024*1024)) + " MB";
			else if(i < 1024*1024*1024*1024)
				return QString::number(i/(1024*1024*1024)) + " GB";
			return "";
		//Max seen rate
		case 19:
			return QString::number(v->toDouble()*0.1) + " Mb/s";
			break;
		//Encoding
		case 20:
			switch(v->toInt())
			{
				case 1: return "CCK";
				case 2: return "PBCC";
				case 3: return "OFDM";
				default: return "Unknown";
			}
		default:
			return v->toString();
	}
}

AlertOptions::AlertOptions()
{
	if(AleOptions.size() == 0)
	{	

	AleName	= "ALERT";


	AleOptions	<< "sec" << "usec" << "header" <<
		"bssid" << "source" << "dest" << 
		"other" << "channel" << "text";

	AleNames	<< "Time" << "uTime" << "Header" << 
		"BSSID" << "Source" << "Destination" << 
		"Other" << "Channel" << "Text";

	}

	Caps	= &AleOptions;
	Names	= &AleNames;
	cName	= &AleName;
	refc	= new int[Names->size()];
	memset(refc,0,sizeof(int)*Names->size());
}

QString AlertOptions::print(QVariant *v,int i)
{
	return v->toString();
}

InfoOptions::InfoOptions()
{
	if(InfOptions.size() == 0)
	{	

	InfName	= "INFO";


	InfOptions  << "networks" << "packets" << "crypt" << 
		"weak" << "noise" << "dropped" << "rate" << "signal";

	InfNames  << "Networks" << "Packets" << "Crypt" << 
		"Weak" << "Noise" << "Dropped" << "Rate" << "Signal";

	}

	Caps	= &InfOptions;
	Names	= &InfNames;
	cName	= &InfName;
	refc	= new int[Names->size()];
	memset(refc,0,sizeof(int)*Names->size());
}

ClientOptions::ClientOptions()
{
	if(CliOptions.size() == 0)
	{	

	CliName	= "CLIENT";

	CliOptions	<< "bssid" << "mac" << "type" << 
		"firsttime" << "lasttime" << "manufkey" << 
		"manufscore" << "datapackets" << "cryptpackets" << 
		"weakpackets" << "gpsfixed" << 
		"minlat" << 
		"minlon" << "minalt" << "minspd" << "maxlat" << 
		"maxlon" << "maxalt" << "maxspd" << "agglat" << 
		"agglon" << "aggalt" << "aggpoints" << "maxrate" << 
		"quality" << "signal" << "noise" << "bestquality" << 
		"bestsignal" << "bestnoise" << "bestlat" << 
		"bestlon" << "bestalt" << "atype" << "ip" << 
		"datasize" << "maxseenrate" << "encodingset" << 
		"decrypted" << "wep";
	}

	Caps	= &CliOptions;
	Names	= &CliNames;
	cName	= &CliName;
	refc	= new int[Caps->size()];
	memset(refc,0,sizeof(int)*Caps->size());
}

QString ClientOptions::print(QVariant *v,int i)
{
	return v->toString();
}

bool ClientOptions::setOption(QString option,bool enable)
{
	if(option == "rangeip")
		option	= "ip";
	return QKismetOptions::setOption(option,enable);
}

CardOptions::CardOptions()
{
	if(CrdOptions.size() == 0)
	{	

	CardName	= "CARD";

	CrdOptions	<< "interface" << "type" << "username" 
			<< "channel" << "id" << "packets" 
			<< "hopping";	
	}

	Caps	= &CrdOptions;
	Names	= &CrdNames;
	cName	= &CardName;
	refc	= new int[Caps->size()];
	memset(refc,0,sizeof(int)*Caps->size());
}

QString CardOptions::print(QVariant *v,int i)
{
	return v->toString();
}
